import threading,os,time
from threading import Thread,Condition
from config.setting import base_header
from hashlib import md5
from config.user_setting import MAX_DOWNLOAD_FILE_THREAD,FILE_DOWNLOAD_PATH,DOWNLOAD_THREAD_MEANWHILE_COUNT
from pixiv.file_thread_download import thread_file_download
class file_download():

    def __init__(self,url,s):
        base_header['Referer'] = url
        self.url = url
        self.s = s
        if url != "":
            for i in range(5):
                try:
                    res = s.get(self.url)
                    break
                except:
                    print('文件下载失败','8秒后开始','第',(i+1),'尝试')
                    time.sleep(8)
            self.filesize = int(res.headers['Content-Length'])
            self.context = res.content
            self.filemd5 = md5(self.context).hexdigest()
            self.filename = FILE_DOWNLOAD_PATH + url.split('/')[-1]

    def setUrl(self,url):
        self.url = url
        for i in range(5):
            try:
                res = self.s.get(self.url)
                break
            except:
                print('文件下载失败','8秒后开始','第',(i+1),'尝试')
                time.sleep(8)
            
        self.filesize = int(res.headers['Content-Length'])
        self.context = res.content
        self.filemd5 = md5(self.context).hexdigest()
        self.filename = FILE_DOWNLOAD_PATH + url.split('/')[-1]
    def download_thread(self):
        '''
        多线程下载
        '''
        if(self.is_exist_file()):
            #线程数
            threadnum = DOWNLOAD_THREAD_MEANWHILE_COUNT
            #信号量，同时只允许3个线程运行
            sema = threading.BoundedSemaphore(threadnum)
            # 默认3线程现在，也可以通过传参的方式设置线程数
            step = self.filesize // threadnum
            mtd_list = []
            start = 0
            end = -1

            tempf = open(self.filename,'w')
            tempf.close()

            with open(self.filename,'rb+') as  f:
                fileno = f.fileno()
                # 如果文件大小为11字节，那就是获取文件0-10的位置的数据。如果end = 10，说明数据已经获取完了。
                while end < self.filesize -1:
                    start = end +1
                    end = start + step -1
                    if end > self.filesize:
                        end = self.filesize
                    # print("start:%s, end:%s"%(start,end))
                    # 复制文件句柄
                    dup = os.dup(fileno)
                    # print(dup)
                    # 打开文件
                    fd = os.fdopen(dup,'rb+',-1)
                    # print(fd)
                    t = thread_file_download(self.url,start,end,fd,self.s,sema)
                    t.start()
                    mtd_list.append(t)
                    
                # 等待线程结束
                for i in  mtd_list:
                    i.join()
                self.record_md5()
        else:
             print("文件已经存在",self.filename)
    
    def download(self):
        '''
        单线程下载
        '''
        if(self.is_exist_file()):
            with open(self.filename,'wb') as f:
                f.write(self.context)
            self.record_md5()
        else:
            print("文件已经存在",self.filename)

    def auto_select_download(self):
        '''
        根据文件大小自动选择下载方式
        '''
        if self.filesize > MAX_DOWNLOAD_FILE_THREAD :
            self.download_thread()
        else:
            self.download()
    
    def is_exist_file(self):
        '''
        判断文件是否存在
        '''
       
        if(os.path.exists(self.filename)):
             lis = []
             with open('image/md5.dd','r') as f:
                lis = f.read().splitlines()
             if self.filemd5 in lis :
                 return False
             else:
                 self.filename = self.filemd5
                 return True
        return True
        
    def record_md5(self):
        '''
        记录下载文件的md5
        '''
        if self.is_exist_file():
            with open('image/md5.dd','a+') as f:
                f.write(self.filemd5+'\n')

 

  